﻿using EntityFrameworkETL.SaveBatchedChanges;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Infrastructure.Interception;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EntityFrameworkETL.Interceptors
{
    public class ComplexInsertInterceptor : IDbCommandInterceptor
    {
        #region UnusedMembers
        public void NonQueryExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
        {
            throw new NotImplementedException();
        }

        public void NonQueryExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
        {
            throw new NotImplementedException();
        }

        public void ReaderExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)
        {
        }

        public void ScalarExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
        {
            throw new NotImplementedException();
        }

        public void ScalarExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
        {
            throw new NotImplementedException();
        }

        #endregion

        public ComplexInsertInterceptor()
        {
            BatchedCommandCacheItems = new List<DbCommandCacheItem>();
        }

        public List<DbCommandCacheItem> BatchedCommandCacheItems { get; set; }
        public DbCommandCacheItem PreviosDbCommandCacheItem { get; set; }

        public long FakePKs { get; set; }
        public string TopLevelName { get; set; }
        public void ReaderExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)
        {
            interceptionContext.SuppressExecution();
            var dataTable = new DataTable("FakeResults");
            dataTable.Columns.Add(new DataColumn("Id", typeof(Int32)));
            var dr = dataTable.NewRow();
            FakePKs -= 1;
            dr["Id"] = FakePKs;
            dataTable.Rows.Add(dr);
            interceptionContext.Result = dataTable.CreateDataReader();
            var currentBatchedCommand = new DbCommandCacheItem(FakePKs, command);
            if (PreviosDbCommandCacheItem == null)
            {
                PreviosDbCommandCacheItem = currentBatchedCommand;
                TopLevelName = PreviosDbCommandCacheItem.TableName;
            }
            if (currentBatchedCommand.TableName == TopLevelName)
            {
                BatchedCommandCacheItems.Add(currentBatchedCommand);
            }
            else if (currentBatchedCommand.TableName == PreviosDbCommandCacheItem.TableName)
            {
                PreviosDbCommandCacheItem.ParentCommand.ChildCommands.Add(currentBatchedCommand);
            }
            else if (PreviosDbCommandCacheItem.HasAncestor(currentBatchedCommand))
            {
                var ancestor = PreviosDbCommandCacheItem.GetAncestor(currentBatchedCommand);
                ancestor.ParentCommand.ChildCommands.Add(currentBatchedCommand);
                currentBatchedCommand.ParentCommand = ancestor.ParentCommand;
            }
            else
            {
                //new child
                PreviosDbCommandCacheItem.ChildCommands.Add(currentBatchedCommand);
                currentBatchedCommand.ParentCommand = PreviosDbCommandCacheItem;
            }

            PreviosDbCommandCacheItem = currentBatchedCommand;

        }


    }
}
